package com.hexb.smh.controller.management;

import com.hexb.core.common.Page;
import com.hexb.core.utils.MapBuilder;
import com.hexb.smh.annotations.AopOperationLog;
import com.hexb.smh.entity.Account;
import com.hexb.smh.entity.enums.Operators;
import com.hexb.smh.entity.enums.RoleType;
import com.hexb.smh.entity.param.account.AccountParam;
import com.hexb.smh.entity.param.account.AccountQueryParam;
import com.hexb.smh.entity.param.account.PasswordModifierParam;
import com.hexb.smh.entity.view.SimpleAccount;
import com.hexb.smh.service.IAccountService;
import com.hexb.smh.utils.OperationConst;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.objects.annotations.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

import java.util.List;

import static com.hexb.smh.utils.SmhConstant.*;

/**
 * @author : hexb
 */
@RestController
@RequestMapping("/management/account/admin")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(value = "A2.管理员帐号", description = "Server", tags = {"A2.管理员帐号"})
public class AdminController {

    final private IAccountService userService;


    @ApiOperation(value = "获取管理员(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageSize", value = "分页大小")
            , @ApiImplicitParam(name = "pageNum", value = "当前页(第1页为1)")
    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @GetMapping("/{pageSize}/{pageNum}")
    public Page<Account> pageAdmin(AccountQueryParam param,
                                   @PathVariable int pageSize,
                                   @PathVariable int pageNum) {
        param.setRole(param.getRole() == null ? RoleType.admin : param.getRole());
        return userService.search(param, pageSize, pageNum);
    }


    @AopOperationLog(name = OperationConst.APPEND_ADMIN, operations = Operators.appendAccount)
    @ApiOperation("添加管理员")
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PostMapping
    public Account appendAdmin(@RequestBody @Valid AccountParam.AccountParamInsert param) {
        Account account = param.toAdmin();
        userService.save(account);
        return account;
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号Id")
    })
    @ApiOperation("更新管理员")
    @AopOperationLog(name = OperationConst.UPDATE_ADMIN, operations = Operators.updateAccount)
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PutMapping("/{id}")
    public Account updateAdmin(@PathVariable Integer id,
                               @RequestBody @Valid AccountParam.AccountParamUpdate param) {
        Account account = param.toAccount(id);
        userService.update(account);
        return account;
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号Id")
    })
    @ApiOperation("注销(删除)管理员")
    @AopOperationLog(name = OperationConst.DELETE_ADMIN, operations = Operators.deleteAccount)
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @DeleteMapping("/{id}")
    public int updateAdmin(@PathVariable Integer id) {
        return userService.delete(id);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号Id")
    })
    @ApiOperation("启用管理员")
    @AopOperationLog(name = OperationConst.ENABLE_ADMIN, operations = Operators.enableAccount)
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PutMapping("/enable/{id}")
    public Account enableAdmin(@PathVariable Integer id) {
        return userService.toggleAccount(id, true);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号Id")
    })
    @ApiOperation("禁用管理员")
    @AopOperationLog(name = OperationConst.DISABLE_ADMIN, operations = Operators.disableAccount)
    @RequiresRoles(value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PutMapping("/disable/{id}")
    public Account disableAdmin(@PathVariable Integer id) {
        return userService.toggleAccount(id, false);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号Id")
    })
    @ApiOperation("重置管理员密码")
    @AopOperationLog(name = OperationConst.RESET_ADMIN, operations = Operators.resetPassword)
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PutMapping("/reset/{id}")
    public int resetAdmin(@PathVariable Integer id) {
        return userService.restPassword(id);
    }


    @ApiOperation("获取单个管理员信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "管理员id")
    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @GetMapping("/{id}")
    public Account getAdmin(
            @PathVariable int id) {
        return userService.findById(id);
    }


    @ApiOperation("批量删除(注销)")
    @AopOperationLog(name = OperationConst.DELETE_ADMIN, operations = Operators.batchDeleteAccount)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "管理员id列表")
    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @DeleteMapping("/batch/{ids}")
    public int getAdmin(
            @PathVariable Integer[] ids) {
        return userService.deleteBatch(ids);
    }


    @ApiOperation("批量启用")
    @AopOperationLog(name = OperationConst.ENABLE_ADMIN, operations = Operators.batchEnableAccount)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "管理员id列表")
    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PutMapping("/batch/enable/{ids}")
    public int batchEnableAdmin(
            @PathVariable Integer[] ids) {
        return userService.updateEnableBatch(ids, true);
    }

    @ApiOperation("批量禁用")
    @AopOperationLog(name = OperationConst.DISABLE_ADMIN, operations = Operators.batchDisableAccount)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "管理员id列表")
    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    @PutMapping("/batch/disable/{ids}")
    public int batchDisableAdmin(
            @PathVariable Integer[] ids) {
        return userService.updateEnableBatch(ids, false);
    }

    @ApiOperation("检查手机号是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号id(当编辑时需要排除自身帐号时使用)")
            , @ApiImplicitParam(name = "phoneNo", value = "手机号码")

    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_SALESMAN_MANAGER})
    @GetMapping("/phoneNo/checkDuplicate")
    public Boolean checkPhoneDuplicate(String phoneNo, Integer id) {
        Account account = userService.findOneByMap(MapBuilder
                .<String, Object>create("phoneNo", phoneNo)
                .build("withoutId", id).map());
        return null != account;
    }

    @ApiOperation("检查登录名是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "帐号id(当编辑时需要排除自身帐号时使用)")
            , @ApiImplicitParam(name = "loginName", value = "登录名")

    })
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_SALESMAN_MANAGER})
    @GetMapping("/loginName/checkDuplicate")
    public Boolean checkLoginNameDuplicate(String loginName, Integer id) {
        Account account = userService.findOneByMap(MapBuilder
                .<String, Object>create("loginName", loginName)
                .build("withoutId", id).map());
        return null != account;
    }

    @ApiOperation(value = "修改自己密码(包括业务员/管理员)")
    @AopOperationLog(name = OperationConst.CHANGE_PASSWORD, operations = Operators.none)
    @PutMapping("/changePassword")
    @RequiresAuthentication
    public int changePassword(@RequestBody @Valid PasswordModifierParam param) {
        int i = userService.changePassword(param.getOldPassword(), param.getNewPassword());
        SecurityUtils.getSubject().logout();
        return i;
    }


    @ApiOperation(value = "快速查询管理员(用于操作日志自动补全)")
    @GetMapping("/findAdmin")
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    public List<SimpleAccount> findAdmin(String searchKey) {
        return userService.find(searchKey, false);
    }

    @ApiOperation(value = "快速查询所有帐号(用于登录自动补全)")
    @GetMapping("/findAccount")
    @RequiresRoles(logical = Logical.OR, value = {ROLE_SUPER_ADMIN, ROLE_ADMIN})
    public List<SimpleAccount> findAccount(String searchKey) {
        return userService.find(searchKey, true);
    }
}
